package array_stack

type MStack struct {
	SData []interface{}
	MSize int64
	MTop  int64
}

func NewMStack(size int64) *MStack {
	return &MStack{
		SData: make([]interface{}, size),
		MSize: size,
		MTop:  0,
	}
}

func (s *MStack) IsEmpty() bool {
	return s.MTop == 0
}

func (s *MStack) IsFull() bool {
	return s.MTop == s.MSize
}

func (s *MStack) Length() int64 {
	return s.MTop
}

func (s *MStack) Push(elem interface{}) bool {
	if s.IsFull() {
		return false
	}
	s.SData[s.MTop] = elem
	s.MTop++
	return true
}

func (s *MStack) GetTop() (elem interface{}, ok bool) {
	if s.IsEmpty() {
		return nil, false
	}
	return s.SData[s.MTop-1], true
}

func (s *MStack) Pop() (elem interface{}, ok bool) {
	if s.IsEmpty() {
		return nil, false
	}
	s.MTop--
	return s.SData[s.MTop], true
}

func (s *MStack) Traverse(callback func(item interface{}), direction bool) {
	var i int64
	if direction {
		for i = 0; i < s.MTop; i++ {
			callback(s.SData[i])
		}
	} else {
		for i = s.MTop - 1; i >= 0; i-- {
			callback(s.SData[i])
		}
	}
}
